// client.cpp
#define _WIN32_DCOM
#include <iostream.h>
#include <stdio.h>
#include "Component CoInitializeSecurity\component.h"

void main()
{
	cout << "Client: Calling CoInitialize()" << endl;
	CoInitialize(NULL);
		
	IUnknown* pUnknown;
	ISum* pSum;

	cout << "Client: Calling CoCreateInstanceEx() " << endl;

	// Your user, domain, and password below
	COAUTHIDENTITY AuthIdentity;
	AuthIdentity.User = L"User";
	AuthIdentity.UserLength = wcslen(L"User");
	AuthIdentity.Domain = L"Domain";
	AuthIdentity.DomainLength = wcslen(L"Domain");
	AuthIdentity.Password = L"Password";
	AuthIdentity.PasswordLength = wcslen(L"Password");
	AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

	COAUTHINFO AuthInfo;
	AuthInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
	AuthInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
	AuthInfo.pwszServerPrincName = NULL;
	AuthInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CONNECT;
	AuthInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
	AuthInfo.pAuthIdentityData = &AuthIdentity;
	AuthInfo.dwCapabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;

	// Your server name below
	COSERVERINFO ServerInfo;
	ServerInfo.dwReserved1 = 0;
	ServerInfo.pwszName = L"RemoteServerName";
	ServerInfo.pAuthInfo = &AuthInfo;
	ServerInfo.dwReserved2 = 0;

	MULTI_QI qi;
	qi.pIID = &IID_IUnknown;
	qi.pItf = NULL;
	qi.hr = 0;

	HRESULT hr = CoCreateInstanceEx(CLSID_InsideCOM, NULL, CLSCTX_REMOTE_SERVER, &ServerInfo, 1, &qi);
	pUnknown = qi.pItf;

	if(FAILED(hr))
	{
		if(hr == E_ACCESSDENIED)
			printf("CoCreateInstance FAILED hr = E_ACCESSDENTIED\n", hr);
		else
			printf("CoCreateInstance FAILED hr = %0x\n", hr);
		exit(0);
	}

	cout << "Client: Calling QueryInterface() for ISum on " << pUnknown << endl;
	hr = pUnknown->QueryInterface(IID_ISum, (void**)&pSum);
	if(FAILED(hr))
		cout << "QueryInterface FAILED" << endl;

	cout << "Client: Calling Release() for pUnknown" << endl;
	hr = pUnknown->Release();

	cout << "Client: pSum = " << pSum << endl;

	int sum;
	hr = pSum->Sum(4, 9, &sum);
	if(SUCCEEDED(hr))
		cout << "Client: Calling Sum() return value is " << sum << endl;

	cout << "Client: Calling Release() for pSum" << endl;
	hr = pSum->Release();

	cout << "Client: Calling CoUninitialize()" << endl;
	CoUninitialize();
}